﻿Public Class Form1

    Private Structure MOUSEINPUT
        Public dx As Integer
        Public dy As Integer
        Public mouseData As Integer
        Public dwFlags As Integer
        Public dwtime As Integer
        Public dwExtraInfo As Integer
    End Structure

    Private Structure INPUT_TYPE
        Public dwType As Integer
        Public xi As MOUSEINPUT
    End Structure

    Private Declare Function SendInput Lib "user32.dll" ( _
     ByVal nInputs As Integer, ByRef pInputs As INPUT_TYPE, _
     ByVal cbSize As Integer) As Integer

    Private Const INPUT_MOUSE = 0
    Private Const INPUT_KEYBOARD = 1
    Private Const INPUT_HARDWARE = 2
    Private Const WM_KEYDOWN As Integer = 256
    Private Const WM_SYSKEYDOWN As Integer = 260
    Private Const WM_KEYUP As Integer = 257
    Private Const WM_SYSKEYUP As Integer = 261
    Private Const MOUSE_MOVE = &H1
    Private Const MOUSE_LEFTDOWN = &H2
    Private Const MOUSE_LEFTUP = &H4

    Public Sub keyMouseDown(ByVal alsoUp As Boolean)

        Dim inputEvents(0) As INPUT_TYPE

        inputEvents(0).xi.dx = 0
        inputEvents(0).xi.dy = 0
        inputEvents(0).xi.mouseData = 0
        inputEvents(0).xi.dwFlags = MOUSE_LEFTDOWN
        inputEvents(0).xi.dwtime = 0
        inputEvents(0).xi.dwExtraInfo = 0
        inputEvents(0).dwType = INPUT_MOUSE

        SendInput(1, inputEvents(0), Len(inputEvents(0)))

        If alsoUp Then
            keyMouseUp()
        End If
    End Sub

    Public Sub keyMouseUp()

        Dim inputEvents(0) As INPUT_TYPE

        inputEvents(0).xi.dx = 0
        inputEvents(0).xi.dy = 0
        inputEvents(0).xi.mouseData = 0
        inputEvents(0).xi.dwFlags = MOUSE_LEFTUP
        inputEvents(0).xi.dwtime = 0
        inputEvents(0).xi.dwExtraInfo = 0
        inputEvents(0).dwType = INPUT_MOUSE

        SendInput(1, inputEvents(0), Len(inputEvents(0)))
    End Sub

    Public Sub keyMouseMove(ByVal x As Integer, ByVal y As Integer)

        Dim inputEvents(0) As INPUT_TYPE

        inputEvents(0).xi.dx = x
        inputEvents(0).xi.dy = y
        inputEvents(0).xi.mouseData = 0
        inputEvents(0).xi.dwFlags = MOUSE_MOVE
        inputEvents(0).xi.dwtime = 0
        inputEvents(0).xi.dwExtraInfo = 0
        inputEvents(0).dwType = INPUT_MOUSE

        SendInput(1, inputEvents(0), Len(inputEvents(0)))
    End Sub

    Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean

        If (msg.Msg = WM_KEYDOWN) Or (msg.Msg = WM_SYSKEYDOWN) Then

            If (keyData = Keys.Left) Or (keyData = Keys.NumPad4) Then
                keyMouseMove(-3, 0)
            ElseIf (keyData = Keys.Right) Or (keyData = Keys.NumPad6) Then
                keyMouseMove(3, 0)
            ElseIf (keyData = Keys.Up) Or (keyData = Keys.NumPad8) Then
                keyMouseMove(0, -3)
            ElseIf (keyData = Keys.Down) Or (keyData = Keys.NumPad2) Then
                keyMouseMove(0, 3)
            ElseIf (keyData = Keys.Enter) Or (keyData = Keys.NumPad5) Then
                keyMouseDown(True)
            End If

        End If

        Return True
    End Function

    Protected Overrides Function ProcessKeyPreview(ByRef m As System.Windows.Forms.Message) As Boolean

        If (m.Msg = WM_KEYUP) Or (m.Msg = WM_SYSKEYUP) Then

            If m.WParam = Keys.Enter Then
                keyMouseUp()
            End If

        End If

    End Function
End Class
